package com.ken.common.mysql.plugins;

import com.ken.common.mysql.utils.MybatisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Statement;

/**
 * SQL记录的Mybatis插件
 * 1、记录当前执行的sql语句
 * 2、记录当前sql语句的执行时间
 *
 * type - 表示当前要增强的内置对象的类型（必须是4大内置对象中的一个）
 * method - 表示增强内置对象中的具体方法名
 * args - 方法的形参列表（避免方法重载而无法识别具体增强的方法是哪一个）
 */
@Intercepts({
        @Signature(
                type = StatementHandler.class,
                method = "query",
                args = {Statement.class, ResultHandler.class}
        ),
        @Signature(
                type = StatementHandler.class,
                method = "update",
                args = {Statement.class}
        )
})
@Slf4j
public class SQLPlugin implements Interceptor {

    /**
     * 拦截方法
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        //获得当前执行的SQL语句
        StatementHandler statementHandler = MybatisUtils.getNoProxyTarget(invocation.getTarget());
        System.out.println("SQLPlugin当前的statementHandler:" + statementHandler.getClass().getName());
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql().replace("\n", "");
        log.debug("[SQL] - exec sql - [{}]", sql);

        //记录当前的执行时间
        long begin = System.currentTimeMillis();
        Object result = invocation.proceed();//放行 - 执行实际的方法
        long end = System.currentTimeMillis();
        log.debug("[SQL] - exec sql time - [{}s]", BigDecimal.valueOf(end - begin).divide(BigDecimal.valueOf(1000)).setScale(6, RoundingMode.DOWN).doubleValue());

        return result;
    }
}
